package com.lakala.sh.zf.openplatform.main;

import com.lakala.sh.zf.openplatform.common.RSAUtil;
import com.lakala.sh.zf.openplatform.common.RandomUtils;
import com.lakala.sh.zf.openplatform.common.SecureUtils;
import org.apache.commons.codec.binary.Base64;

import java.io.UnsupportedEncodingException;
import java.security.Key;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Map;

/**
 * @Author peijian
 * @Date 2021/1/18 17:00
 * @Version 1.0
 * 生成公私钥，签名及验签
 */
public class OpenplatformDemo {

    private static final String SIGNATURE_ALGORITHM = "SHA256withRSA";

    public static final String PUBLIC_KEY = "PublicKey";
    public static final String PRIVATE_KEY = "PrivateKey";

    public static void main(String[] args) {
        String appId = "12345678";
        String serialNo = "1745381c327";
        String timestamp = String.valueOf((int)(System.currentTimeMillis()/1000));
        String nonce = RandomUtils.generateString(12);
        String reqBody = "bodyContent";

        try {
            System.out.println("开始构建秘钥操作");
            Map<String, Key> keyMap = RSAUtil.initKey();// 构建密钥
            PublicKey publicKey = (PublicKey) keyMap.get(PUBLIC_KEY);
            PrivateKey privateKey = (PrivateKey) keyMap.get(PRIVATE_KEY);

            System.out.println("开始执行加签操作");
            String signature = sign(appId, serialNo, timestamp, nonce, reqBody, privateKey);
            System.out.println("生成签名内容,"+signature);
            System.out.println("开始执行验签操作");
            verifySign(appId, serialNo, timestamp, nonce, reqBody, signature, publicKey);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 加签
     * @param appId：拉卡拉分配的appId
     * @param serialNo：拉卡拉提供的公钥的证书序列号
     * @param timestamp：时间戳
     * @param nonce：随机数
     * @param reqBody：请求报文
     * @param privateKey：私钥
     * @return
     */
    private static String sign(String appId, String serialNo, String timestamp, String nonce, String reqBody ,PrivateKey privateKey) {
        String preSignData=appId+"\n"+serialNo+"\n"+timestamp+"\n"+nonce +"\n"+reqBody +"\n";
        System.out.println("准备加签名的数据："+preSignData);
        byte[] sign = new byte[0];
        try {
            sign = SecureUtils.sign(SIGNATURE_ALGORITHM, preSignData.getBytes("utf-8"), privateKey);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String signature = new String(Base64.encodeBase64(sign));
        return signature;
    }


    /**
     * 验签
     * @param appId：拉卡拉分配的appId
     * @param serialNo：拉卡拉提供的公钥的证书序列号
     * @param timestamp：时间戳
     * @param nonce：随机数
     * @param reqBody：请求报文
     * @param signature：签名
     * @param publicKey：公钥
     * @throws UnsupportedEncodingException
     */
    private static void verifySign(String appId, String serialNo, String timestamp, String nonce, String reqBody, String signature, PublicKey publicKey) throws UnsupportedEncodingException {
        String preSignData=appId+"\n"+serialNo+"\n"+timestamp+"\n"+nonce +"\n"+reqBody +"\n";
        System.out.println("准备验签名的数据："+preSignData);
        boolean isSignOK = SecureUtils.verify(SIGNATURE_ALGORITHM, preSignData.getBytes("utf-8"), publicKey, Base64.decodeBase64(signature));
        if(isSignOK) {
            System.out.println("签名验证通过");
        } else {
            System.out.println("签名验证不通过");
        }
    }
}
